home *** CD-ROM | disk | FTP | other *** search
- Path: xanth!mcnc!ncsuvx!lll-winken!lll-tis!ames!necntc!ncoast!allbery
- From: wswietse@eutrc3.UUCP (Wietse Venema)
- Newsgroups: comp.sources.misc
- Subject: v03i006: uucp mail for pc's (5 of 8)
- Message-ID: <214@eutrc3.UUCP>
- Date: 20 Apr 88 16:50:16 GMT
- Sender: allbery@ncoast.UUCP
- Reply-To: wswietse@eutrc3.UUCP (Wietse Venema)
- Organization: Tech. Univ. Eindhoven, Neth.
- Lines: 2164
- Approved: allbery@ncoast.UUCP
-
- comp.sources.misc: Volume 3, Issue 6
- Submitted-By: "Wietse Venema" <wswietse@eutrc3.UUCP>
- Archive-Name: pcmail/Part5
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 5 (of 8)."
- # Contents: ascf.c comm.h deskutil.c invoke.c kpres.c logs.c path.h
- # sendwork.c spoolfil.c srctoman.sh switcher.c unalias.c
- # Wrapped by wietse@eutwc1 on Wed Apr 20 16:45:27 1988
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f ascf.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"ascf.c\"
- else
- echo shar: Extracting \"ascf.c\" \(4105 characters\)
- sed "s/^X//" >ascf.c <<'END_OF_ascf.c'
- X/*++
- X/* NAME
- X/* ascf 3
- X/* SUMMARY
- X/* stdio-like ascii filter
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* ascii filtering
- X/* SYNOPSIS
- X/* FILE *ascopen(name,mode)
- X/* char *name;
- X/* char *mode;
- X/*
- X/* int ascget(fp)
- X/* FILE *fp;
- X/*
- X/* int ascclose(fp)
- X/* FILE *fp;
- X/* DESCRIPTION
- X/* The functions in this module provide filtered stream i/o for
- X/* textfiles produced by word processors. Their calling sequence
- X/* has been modelled after the standard i/o library routines.
- X/*
- X/* ascopen() is the analogon of fopen(3), ascget() returns the next
- X/* character in the filtered input stream, and ascclose() closes
- X/* the stream. ascget() is a macro.
- X/*
- X/* The following mappings are done: cr/lf, cr, lf, lf/cr are
- X/* replaced by newline; all high bits are stripped off; wordstar
- X/* hyphens are converted to normal hyphens. Except for tabs,
- X/* all control characters are suppressed in the output.
- X/* In order to avoid problems in mailers, a newline
- X/* character is appended to the last line of each file.
- X/* SEE ALSO
- X/* stdio(3) standard i/o library interface.
- X/* DIAGNOSTICS
- X/* ascopen() returns a null pointer on failure; ascget() returns
- X/* the value EOF when the end of a stream is reached. ascclose()
- X/* returns whatever fclose() returns.
- X/* BUGS
- X/* Actually works with wordstar or clean ascii files only.
- X/* No character pushback.
- X/* Although allowed by ascopen(), the "w" file open mode is
- X/* of no use.
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Mon Jul 6 16:03:41 GMT+1:00 1987
- X/* LAST MODIFICATION
- X/* Mon Apr 4 23:34:46 MET 1988
- X/* VERSION/RELEASE
- X/* 1.4
- X/*--*/
- X
- X#include <ctype.h>
- X
- X#include "defs.h"
- X#include "ascf.h"
- X
- X/* some systems do not define _NFILE in stdio.h */
- X
- X#ifndef _NFILE
- X# include <sys/param.h> /* maybe we are a sun */
- X# ifdef NOFILE
- X# define _NFILE NOFILE
- X# else
- X"ERROR: cannot get max nr of open files"
- X# endif
- X#endif
- X
- X#define CTRL(x) ((x)^0100) /* ASCII control characters */
- X
- X#ifdef MSDOS
- X#include <fcntl.h> /* to turn cr/lf mapping off */
- X#endif
- X
- Xpublic Asc asc[_NFILE]; /* one filter structure per file */
- X
- X/* ascopen - open stream, initialize intermediate buffer */
- X
- Xpublic FILE *ascopen(file,mode)
- Xchar *file,*mode;
- X{
- X register FILE *fp;
- X
- X if (fp = fopen(file,mode)) { /* if file is accessable */
- X register Asc *ap = asc+fileno(fp);
- X if (ap->buf = malloc(BUFSIZ)) { /* if buffer available */
- X ap->cnt = 0; /* init buffer count */
- X ap->nlf = 0; /* no newline appended yet */
- X#ifdef O_BINARY
- X setmode(fileno(fp),O_BINARY);
- X#endif
- X } else {
- X fclose(fp); /* no room for that buffer */
- X fp = 0;
- X }
- X }
- X return(fp);
- X}
- X
- X/* ascclose - release intermediate buffer and close the stream */
- X
- Xpublic int ascclose(fp)
- Xregister FILE *fp;
- X{
- X free(asc[fileno(fp)].buf);
- X return(fclose(fp));
- X}
- X
- X/* ascbuf - ascii filter, make new buffer of text */
- X
- Xpublic int ascbuf(fp)
- XFILE *fp;
- X{
- X register Asc *ap = asc+fileno(fp); /* intermediate buffer access */
- X register char *cp = ap->buf; /* init write pointer */
- X register int c; /* single-character input buffer */
- X int d; /* look-ahead character */
- X
- X while (cp < ap->buf+BUFSIZ &&
- X (c = getc(fp)) != EOF && (c &= 0177) != CTRL('Z')) {
- X if (c == ' ' || isprint(c) || c == '\t') {
- X *cp++ = c; /* accept character */
- X } else if ((c == '\r' && ((d = getc(fp)) == '\n' || (ungetc(d,fp),1)))
- X || (c == '\n' && ((d = getc(fp)) == '\r' || (ungetc(d,fp),1)))) {
- X *cp++ = '\n'; /* terminate line */
- X } else if (c == CTRL('_')) {
- X *cp++ = '-'; /* wordstar hyphen */
- X } else {
- X continue; /* ignore other characters */
- X }
- X }
- X if (ap->cnt = cp-ap->buf) { /* anything in the buffer? */
- X ap->ptr = ap->buf; /* yes, set read pointer */
- X return(ascget(fp)); /* and return first character */
- X } else if (ap->nlf == 0) { /* make sure file ends with \n */
- X return(ap->nlf = '\n'); /* append newline first */
- X } else { /* now we're really done */
- X return(EOF); /* that's it. */
- X }
- X}
- END_OF_ascf.c
- if test 4105 -ne `wc -c <ascf.c`; then
- echo shar: \"ascf.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f comm.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"comm.h\"
- else
- echo shar: Extracting \"comm.h\" \(1967 characters\)
- sed "s/^X//" >comm.h <<'END_OF_comm.h'
- X/*++
- X/* NAME
- X/* comm 5
- X/* SUMMARY
- X/* cico systems parameters
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* cico
- X/* SYNOPSIS
- X/* #include "params.h"
- X/* #include "comm.h"
- X/* DESCRIPTION
- X/* .nf
- X
- X/* /* roles and other behavioural codes */
- X
- X#define MASTER 1 /* who sends files */
- X#define SLAVE 2 /* who receives files */
- X#define DONE 3 /* no more files */
- X
- X#define YES 'Y'
- X#define NO 'N'
- X
- X/* /* communications parameters (see params.h) */
- X
- X#define COMM_LINE (comm[P_PORT].strval)
- X#define COMM_RATE (comm[P_BAUD].strval)
- X#define DIAL_SEQUENCE (comm[P_DIAL].strval)
- X#define LOGIN_NAME (comm[P_LOGIN].strval)
- X#define DISC_SEQUENCE (comm[P_DISC].strval)
- X
- X/* /* related info */
- X
- Xextern int ttfd; /* comm. port */
- Xextern Info *comm; /* comm. info */
- Xextern char *password; /* password */
- Xextern char rmthost[]; /* remote system name */
- X
- X/* /* functions that use the above */
- X
- Xextern char *rmtname(); /* make remote spool-file name */
- Xextern char *locname(); /* make local spool-file name */
- X
- X/* /* protocol function pointers */
- X
- Xextern int (*Read)(); /* protocol read */
- Xextern int (*Write)(); /* protocol write */
- Xextern int (*Close)(); /* protocol close */
- X
- X/* /* use these at your own risk */
- X
- X#define MSGBUF 4096 /* message buffer size */
- X
- Xextern char msgin[MSGBUF]; /* message receive buffer */
- Xextern char msgout[MSGBUF]; /* message send buffer */
- X
- X/* /* message i/o functions */
- X
- Xextern int isok(); /* do request; get yes or no */
- Xextern char *talk(); /* send message */
- Xextern char *hear(); /* receive message */
- X/* SEE ALSO
- X/* comm(3) implementation module
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Sun Apr 12 13:52:39 GMT+1:00 1987
- X/* LAST MODIFICATION
- X/* Mon Apr 4 23:36:42 MET 1988
- X/* VERSION/RELEASE
- X/* 1.3
- X/*--*/
- END_OF_comm.h
- if test 1967 -ne `wc -c <comm.h`; then
- echo shar: \"comm.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f deskutil.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"deskutil.c\"
- else
- echo shar: Extracting \"deskutil.c\" \(4943 characters\)
- sed "s/^X//" >deskutil.c <<'END_OF_deskutil.c'
- X/*++
- X/* NAME
- X/* deskutil 3
- X/* SUMMARY
- X/* utility functions
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* mailsh
- X/* SYNOPSIS
- X/* #include "mailsh.h"
- X/*
- X/* void patience()
- X/*
- X/* int when()
- X/*
- X/* int delete()
- X/*
- X/* int unspool()
- X/*
- X/* int print()
- X/*
- X/* int save()
- X/*
- X/* char *tstamp(ltime)
- X/* long *ltime()
- X/* DESCRIPTION
- X/* tstamp() converts absolute time to a string. If called with
- X/* recent time argument (less than 100 days ago) the string will
- X/* be of the form "Sun Apr 17 12:50", otherwise "Sun Apr 17 1988".
- X/*
- X/* delete() gives the user another chance before a message is deleted.
- X/*
- X/* unspool() actually deletes a message. As a side effect it destroys
- X/* the current mail box display so that the next display will
- X/* reflect the actual status of the spool directory.
- X/* The affected message and meta file names are taken from the
- X/* global "message" and "commant" string variables.
- X/*
- X/* print() copies a pager file to the printer.
- X/*
- X/* save() asks where the pager file should be saved.
- X/*
- X/* when() should be called after the user has entered a mail destination
- X/* address. It informs the user that messages are not sent right away,
- X/* but after selection of the Network option in the main menu.
- X/*
- X/* patience() prints a 'one moment please' message in the middle
- X/* screen window. As a side effect, the current pager file is set
- X/* to none.
- X/* FILES
- X/* mail header files in the spool directory
- X/* SEE ALSO
- X/* pager(3), pager(5), kbdinp(3)
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Tue May 12 15:35:20 GMT+1:00 1987
- X/* LAST MODIFICATION
- X/* Mon Apr 4 23:38:26 MET 1988
- X/* VERSION/RELEASE
- X/* 1.3
- X/*--*/
- X
- X#include <errno.h>
- X
- X#include "defs.h"
- X#include "pager.h"
- X#include "mailsh.h"
- X#include "screen.h"
- X#include "status.h"
- X
- Xhidden int save_desk();
- X
- X/* patience - say this will take some time */
- X
- Xpublic void patience()
- X{
- X static char *m_wait[] = {
- X "",
- X "One moment please...",
- X 0,
- X };
- X
- X register File *pp = open_pager(); /* create pager file */
- X
- X mesg_pager(pp,m_wait); /* write pager file */
- X ds_pager(); /* show om middle window */
- X close_pager(pp); /* forget pager file */
- X}
- X
- X/* delete - user wants to delete a message; ask for confirmation */
- X
- Xpublic int delete()
- X{
- X static Screen screen[] = {
- X ESCCR, "Enter", unspool,int_error,
- X 0, 0, 0,
- X "Press ESC to cancel. Confirm with ENTER",
- X };
- X
- X return(kbdinp(screen)|S_REDRAW);
- X}
- X
- X/* unspool - actually delete a message; force mail box display rebuild */
- X
- Xpublic int unspool()
- X{
- X if (((chmod(message,0666) || unlink(message)) && errno != ENOENT)
- X || ((chmod(comment,0666) || unlink(comment)) && errno != ENOENT)) {
- X errdisp(E_UNLINK); /* notify user of problem */
- X return(S_REDRAW); /* say screen has changed */
- X } else {
- X junk_desk(); /* say mail box has changed */
- X return(S_BREAK); /* no more work to do */
- X }
- X}
- X
- X/* print - print pager display on default printer */
- X
- Xpublic int print()
- X{
- X return(pr_pager() ? (errdisp(E_PRINTERR),S_REDRAW) : 0);
- X}
- X
- X/* save - ask where pager display should be copied to */
- X
- Xpublic int save()
- X{
- X static Screen screen[] = {
- X STRING, 0, save_desk,int_error,
- X 0, 0, 0,
- X "Press ESC to cancel. Save to file:",
- X };
- X
- X kbdinp(screen); /* prompt for file name, then copy */
- X return(S_REDRAW); /* force screen repaint */
- X}
- X
- X/* save_desk - copy pager file to ordinary file */
- X
- Xhidden int save_desk(to)
- Xchar *to;
- X{
- X if (cp_pager(to)) { /* if file copy failed */
- X unlink(to); /* remove that file */
- X errdisp(E_WRITERR); /* notify the user */
- X return(S_BREAK|S_REDRAW); /* redisplay, terminate caller */
- X } else {
- X junk_file(); /* say file display maybe outdated */
- X return(S_BREAK); /* terminate caller */
- X }
- X}
- X
- X/* when - say when mail will actually be sent */
- X
- Xpublic int when()
- X{
- X static char *msg[] = {
- X "",
- X "To send messages through the network, use the Network",
- X "option in the main menu.",
- X 0,
- X };
- X File *pp = open_pager(); /* open new pager file */
- X
- X mesg_pager(pp,msg); /* fill pager file */
- X ds_pager(); /* display the file */
- X close_pager(pp); /* forget pager file */
- X return(0); /* don't care value */
- X}
- X
- X/* tstamp - time format as produced by the ls(1) command */
- X
- Xpublic char *tstamp(ltime)
- Xlong *ltime;
- X{
- X static char buf[25];
- X
- X /*
- X * Output from asctime() is of the form
- X * "Sun Apr 17 13:34:35 1988"
- X * Depending on how recent the time in question is, we
- X * supress the time or year field.
- X */
- X
- X (void) strcpy(buf,asctime(localtime(ltime)));
- X if (time((long *)0)-*ltime > 60L*60L*24L*100L) {
- X buf[24] = '\0'; /* remove the \n */
- X (void) strcpy(buf+11,buf+19); /* old file, show year */
- X } else
- X buf[16] = '\0'; /* recent, show time */
- X return(buf);
- X}
- END_OF_deskutil.c
- if test 4943 -ne `wc -c <deskutil.c`; then
- echo shar: \"deskutil.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f invoke.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"invoke.c\"
- else
- echo shar: Extracting \"invoke.c\" \(4946 characters\)
- sed "s/^X//" >invoke.c <<'END_OF_invoke.c'
- X/*++
- X/* NAME
- X/* invoke 3
- X/* SUMMARY
- X/* system-dependent process control stuff
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* mailsh
- X/* SYNOPSIS
- X/* #include "status.h"
- X/*
- X/* int invokelp(arg0,arg1,...)
- X/* char *arg0,*arg1,...
- X/*
- X/* int invokevp(argv)
- X/* char **argv;
- X/*
- X/* int onexit(command)
- X/* char *command;
- X/* DESCRIPTION
- X/* invokelp() creates a child process to execute a command.
- X/* arg0, arg1,... is a null-terminated list of string pointers,
- X/* the first being the name of the program. Use is made
- X/* of the search path to locate the program in arg0.
- X/*
- X/* invokevp() is similar to invokelp; the difference is that
- X/* argv is an array of pointers to arguments.
- X/*
- X/* onexit() executes a command, thereby terminating the current process.
- X/* DIAGNOSTICS
- X/* invokelp(), invokevp() return the exit status of the child process,
- X/* E_SYSFAIL if there were insufficient resources, and
- X/* E_NOPROG if the program in arg0 or argv[0] could not be found.
- X/*
- X/* onexit() return -1 if there were problems.
- X/* BUGS
- X/* The invokexx() functions should not be used if the command needs to
- X/* be handled by a command-language processor (e.g. shell built-ins,
- X/* or i/o redirection).
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Sun Apr 5 15:27:37 GMT+1:00 1987
- X/* LAST MODIFICATION
- X/* Wed Apr 6 00:19:56 MET 1988
- X/* VERSION/RELEASE
- X/* 1.4
- X/*--*/
- X
- X#include <errno.h>
- X#include "defs.h"
- X#include "status.h"
- X
- X#ifdef MSDOS
- X#include <process.h>
- X#endif
- X
- X/* invokelp - create child process to execute command */
- X
- X/* VARARGS2 */
- X
- Xpublic int invokelp(arg0,arg1,arg2,arg3,arg4)
- Xchar *arg0,*arg1,*arg2,*arg3,*arg4;
- X{
- X /*
- X * On unix systems we fork a process and overlay the child with
- X * the desired program.
- X * This means we get -1 if the fork did not succeed, otherwise
- X * the exit status if the child process. The code is a bit elaborate
- X * since we want to handle various error conditions.
- X */
- X#ifdef unix
- X register int pid;
- X
- X if ((pid = fork()) < 0) { /* fork off a process */
- X return(E_SYSFAIL); /* resources exhausted */
- X } else if (pid == 0) { /* this is the child process */
- X execlp(arg0,arg0,arg1,arg2,arg3,arg4);/* try to replace it */
- X _exit(errno == ENOENT ? E_NOPROG : E_SYSFAIL); /* sorry, failed */
- X /* NOTREACHED */
- X } else {
- X int xstat,wstat; /* wait till above child terminates */
- X while ((wstat = wait(&xstat)) != -1 && wstat != pid)
- X /* void */ ;
- X if (wstat == -1) {
- X return(E_SYSFAIL); /* oops: no child! */
- X } else if (xstat&0377) {
- X return(E_UNKNOWN); /* child was killed */
- X } else {
- X return(xstat>>8); /* child died naturally */
- X }
- X /* NOTREACHED */
- X }
- X#endif
- X
- X /*
- X * On MS-DOS systems we try to avoid the command.com shell because
- X * it always returns a zero status code.
- X */
- X#ifdef MSDOS
- X int stat;
- X char *p;
- X
- X if ((stat = spawnlp(P_WAIT,arg0,arg0,arg1,arg2,arg3,arg4)) < 0
- X && errno == ENOENT
- X && (strcmp(p = arg0+strlen(arg0)-4,".bat") == 0 || strcmp(p,".BAT") == 0))
- X stat = spawnlp(P_WAIT,"command","command","/c",arg0,arg1,arg2,arg3,arg4);
- X return(stat >= 0 ? stat : (errno == ENOENT ? E_NOPROG : E_SYSFAIL));
- X#endif
- X}
- X
- X/* invokelp - create child process to execute command */
- X
- Xpublic int invokevp(argv)
- Xchar **argv;
- X{
- X /*
- X * On unix systems we fork a process and overlay the child with
- X * the desired program.
- X * This means we get -1 if the fork did not succeed, otherwise
- X * the exit status if the child process. The code is a bit elaborate
- X * since we want to handle various error conditions.
- X */
- X#ifdef unix
- X register int pid;
- X
- X if ((pid = fork()) < 0) { /* fork off a process */
- X return(E_SYSFAIL); /* resources exhausted */
- X } else if (pid == 0) { /* this is the child process */
- X execvp(*argv,argv); /* try to replace it */
- X _exit(errno == ENOENT ? E_NOPROG : E_SYSFAIL); /* sorry, failed */
- X /* NOTREACHED */
- X } else {
- X int xstat,wstat; /* wait till above child terminates */
- X while ((wstat = wait(&xstat)) != -1 && wstat != pid)
- X /* void */ ;
- X if (wstat == -1) {
- X return(E_SYSFAIL); /* oops: no child! */
- X } else if (xstat&0377) {
- X return(E_UNKNOWN); /* child was killed */
- X } else {
- X return(xstat>>8); /* child died naturally */
- X }
- X /* NOTREACHED */
- X }
- X#endif
- X
- X /*
- X * On MS-DOS systems we try to avoid the command.com shell because
- X * it always returns a zero status code.
- X */
- X#ifdef MSDOS
- X int stat;
- X
- X return((stat = spawnvp(P_WAIT,*argv,argv)) >= 0 ?
- X stat : (errno == ENOENT ? E_NOPROG : E_SYSFAIL));
- X#endif
- X}
- X
- X/* onexit - exec another command */
- X
- Xint onexit(command)
- Xchar *command;
- X{
- X if (command && *command) {
- X#ifdef unix
- X return(execlp("/bin/sh","sh","-c",command));
- X#endif
- X
- X#ifdef MSDOS
- X return(system(command));
- X#endif
- X }
- X}
- END_OF_invoke.c
- if test 4946 -ne `wc -c <invoke.c`; then
- echo shar: \"invoke.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f kpres.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"kpres.c\"
- else
- echo shar: Extracting \"kpres.c\" \(4951 characters\)
- sed "s/^X//" >kpres.c <<'END_OF_kpres.c'
- X/*++
- X/* NAME
- X/* kpres
- X/* SUMMARY
- X/* k-protocol presentation layer
- X/* PACKAGE
- X/* uucp across thenet
- X/* SYNOPSIS
- X/* #include "kp.h"
- X/*
- X/* kopen(fd)
- X/* int fd;
- X/*
- X/* kwrite(fd,buf,len)
- X/* int fd,len;
- X/* char *buf;
- X/*
- X/* kread(fd,buf,len)
- X/* int fd,len;
- X/* char *buf;
- X/*
- X/* kclose(fd)
- X/* int fd;
- X/* DESCRIPTION
- X/* This section contains functions that imitate standard unix
- X/* unbuffered i/o facilities. A status code of FAIL is returned when
- X/* the network partner wants to terminate the protocol, or when the
- X/* the transmission error rate is excessive.
- X/*
- X/* Eight-bit data bytes are transported as harmless six-bit data bytes
- X/* in the ASCII range 32 through 95. This introduces an overhead of 33%.
- X/* For textfiles, this is hardly worse than kermit (typical overhead
- X/* 10 %). For binary files the overhead is much less than with kermit
- X/* (typical overhead 60%).
- X/*
- X/* Kopen() sets up the terminal characteristics of the specified file
- X/* descriptors (no echo, raw, tandem). Always returns zero status.
- X/*
- X/* Kwrite() attempts to send the bytes in buf. A zero-length buffer
- X/* should be written to indicate an end-of-file condition. Return status:
- X/* the number of bytes requested, or FAIL.
- X/*
- X/* Kread() attempts to read the requested number of bytes. Status code:
- X/* the number of bytes actually read, or FAIL. A read of zero bytes
- X/* normally indicates an end-of-file condition (see kwrite).
- X/*
- X/* Kclose() sends a protocol abort sequence to the network partner.
- X/* This function should be called to terminate the k protocol driver
- X/* at the other end, or to confirm reception of a protocol abort sequence.
- X/* Kclose always returns zero exit status.
- X/*
- X/* The function kfail() is called by the strategy layer functions to
- X/* indicate protocol failure or termination.
- X/* FUNCTIONS AND MACROS
- X/* kwproto, krproto, kclsproto
- X/* BUGS
- X/* Zero byte read/writes are a clumsy way to handle end-of-files.
- X/* They have been implemented for the sake of compatibility with uucico.
- X/* AUTHOR(S)
- X/* Wietse Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Mon Feb 3 11:14:13 MET 1986
- X/* LAST MODIFICATION
- X/* Mon Apr 4 23:43:28 MET 1988
- X/* VERSION/RELEASE
- X/* 1.3
- X/*--*/
- X
- X#ifdef unix
- X# ifdef SIII
- X# include <termio.h>
- X# else
- X# include <sgtty.h>
- X# endif
- X#endif
- X#include <setjmp.h>
- X#include "kp.h"
- X
- Xstatic jmp_buf Failbuf;
- X
- Xkfail()
- X{
- X longjmp(Failbuf,TRUE);
- X}
- X
- Xkopen(fd)
- Xint fd;
- X{
- X#ifdef unix
- X# ifdef SIII
- X struct termio ttymode;
- X
- X ioctl(fd,TCGETA,&ttymode);
- X ttymode.c_iflag = IXOFF|IXON|ISTRIP;
- X ttymode.c_cc[VMIN] = 1;
- X ttymode.c_cc[VTIME] = 0;
- X ioctl(fd,TCSETA,&ttymode);
- X# else
- X struct sgttyb ttymode;
- X
- X gtty(fd,&ttymode);
- X ttymode.sg_flags |= (TANDEM|RAW);
- X ttymode.sg_flags &= ~(ECHO|CBREAK);
- X stty(fd,&ttymode);
- X# endif
- X#else
- X xioctl(1);
- X#endif
- X return 0;
- X}
- X
- Xkwrite(fd,buf,len)
- Xint fd;
- Xregister char *buf;
- Xregister int len;
- X{
- X static char packbuf[MAXPACKSIZ];
- X static char *packptr = packbuf;
- X register int c,i,rest,shift;
- X
- X /* set error trap */
- X
- X if (setjmp(Failbuf))
- X return FAIL;
- X
- X /* if 'end of data' send null packet */
- X
- X if (len <= 0) {
- X kwproto(fd,NULLP,0);
- X return 0;
- X
- X /* expand 3 eight-bit bytes to four six-bit bytes */
- X
- X } else {
- X for (rest = shift = i = 0; i < len; shift = (shift+STEP)%OUT,i++) {
- X
- X c = *buf++ & 0377; /* No sign extension */
- X *packptr++ = tosix(rest|(c << shift)); /* Assemble byte */
- X rest = (c >> (OUT-shift)); /* Save unused bits */
- X
- X if (shift == (OUT-STEP)) { /* At byte boundary? */
- X *packptr++ = tosix(rest); /* Make 'fourth' byte */
- X rest = 0; /* No unused bits now */
- X if (packptr-packbuf > PACKSIZ-4) { /* Check packet size */
- X kwproto(fd,packbuf,packptr-packbuf);
- X packptr = packbuf;
- X }
- X }
- X }
- X if (shift) { /* Any bits left? */
- X *packptr++ = tosix(rest); /* Put them there */
- X }
- X if (packptr > packbuf) { /* Flush buffer */
- X kwproto(fd,packbuf,packptr-packbuf); /* Ship it off */
- X packptr = packbuf;
- X }
- X return i;
- X }
- X}
- X
- Xkread(fd,buf,len)
- Xint fd;
- Xchar *buf;
- Xint len;
- X{
- X static char packbuf[MAXPACKSIZ] = "";
- X static char *packptr = packbuf;
- X static int packsiz = 0;
- X register int i,c;
- X static int shift,rest;
- X
- X /* set error trap */
- X
- X if (setjmp(Failbuf))
- X return FAIL;
- X
- X /* read packet if buffer is empty */
- X
- X if (packsiz <= 0) {
- X krproto(fd,packptr = packbuf,&packsiz);
- X rest = shift = 0;
- X }
- X
- X /* unpack (remainder of) buffer; return 0 if empty packet received */
- X
- X for (i = 0; (i < len) && packsiz--; shift = (shift+STEP)%IN)
- X {
- X c = unsix(*packptr++);
- X if (shift)
- X buf[i++] = (rest | (c << (IN-shift)));
- X rest = (c >> shift);
- X }
- X return i;
- X}
- X
- Xkclose(fd)
- Xint fd;
- X{
- X /* not here - pass job to the lower layer that understands packet types */
- X
- X kclsproto(fd);
- X return 0;
- X}
- X
- X
- END_OF_kpres.c
- if test 4951 -ne `wc -c <kpres.c`; then
- echo shar: \"kpres.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f logs.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"logs.c\"
- else
- echo shar: Extracting \"logs.c\" \(4714 characters\)
- sed "s/^X//" >logs.c <<'END_OF_logs.c'
- X/*++
- X/* NAME
- X/* logs 3
- X/* SUMMARY
- X/* error logging, status reports, debugging
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* cico
- X/* SYNOPSIS
- X/* void dbg(fmt[,args]);
- X/* char *fmt;
- X/*
- X/* int open_log();
- X/*
- X/* void log(fmt[,args]);
- X/* char *fmt;
- X/*
- X/* void trap(code,fmt[,args]);
- X/* char *fmt;
- X/* DESCRIPTION
- X/* All functions in this module do some form of logging, and accept
- X/* printf-like format strings with %s, %c, and %S, %C. The latter
- X/* two cause output mapping of arbitrary byte values to printable codes.
- X/*
- X/* dbg() formats its arguments and writes the result to the standard
- X/* output.
- X/*
- X/* open_log() tries to open the logfile for writing. It returns
- X/* a status E_WRITERR if the file could not be opened or created.
- X/*
- X/* log() writes status info to the log file. If debugging is enabled,
- X/* the message is also written to the standard output.
- X/*
- X/* trap() writes a message to the log file and performs a longjmp call
- X/* (systrap) with the status as given in the code parameter. If
- X/* debugging is enabled, the message is also written to the standard
- X/* output.
- X/* FUNCTIONS AND MACROS
- X/* longjmp()
- X/* FILES
- X/* LOGFILE status reports
- X/* BUGS
- X/* Logfile info may be lost if the program terminates abnormally.
- X/* We do not open/close the with each log() call since that would
- X/* slow down performance on floppy-based systems dramatically.
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Thu Mar 26 17:45:19 GMT+1:00 1987
- X/* LAST MODIFICATION
- X/* Mon Apr 4 23:44:00 MET 1988
- X/* VERSION/RELEASE
- X/* 1.3
- X/*--*/
- X
- X#include <setjmp.h>
- X#include <ctype.h>
- X#include <varargs.h>
- X#include "defs.h"
- X#include "logs.h"
- X#include "path.h"
- X#include "status.h"
- X
- X#define dbgout stdout /* where debugging output should go */
- X
- Xhidden FILE *logfp = NULL; /* log file file pointer */
- Xhidden char *visible(); /* map characters to readable codes */
- Xhidden void dprintf(); /* special-purpose formatting function */
- X
- X/* dbg - write debugging info to the debugging output */
- X
- X/* VARARGS1 */
- X
- Xpublic void dbg(fmt,va_alist)
- Xregister char *fmt;
- Xva_dcl
- X{
- X va_list s;
- X
- X va_start(s);
- X dprintf(dbgout,fmt,s);
- X va_end(s);
- X}
- X
- X/* open_log - check the logfile can be written */
- X
- Xpublic int open_log()
- X{
- X if (logfp == NULL && (logfp = fopen(logfile(),"a")) == NULL)
- X return(E_WRITERR);
- X else
- X return(0);
- X}
- X
- X/* log - write status info to the log file */
- X
- X/* VARARGS1 */
- X
- Xpublic void log(fmt,va_alist)
- Xregister char *fmt;
- Xva_dcl
- X{
- X va_list s;
- X
- X /* log file should be open! */
- X
- X if (logfp == NULL)
- X exit(E_CONFUSED);
- X
- X /* write status record to log file */
- X
- X va_start(s);
- X dprintf(logfp,fmt,s);
- X putc('\n',logfp);
- X va_end(s);
- X
- X /* if debugging on, write also to debugging output */
- X
- X if (dflag) {
- X va_start(s);
- X dprintf(dbgout,fmt,s);
- X putc('\n',dbgout);
- X va_end(s);
- X }
- X}
- X
- X/* trap - exception handler */
- X
- X/* VARARGS2 */
- X
- Xpublic void trap(code,fmt,va_alist)
- Xint code;
- Xchar *fmt;
- Xva_dcl
- X{
- X va_list s;
- X
- X /* write exception record to log file */
- X
- X va_start(s);
- X dprintf(logfp,fmt,s);
- X putc('\n',logfp);
- X va_end(s);
- X
- X /* if debugging on, write also to debugging output */
- X
- X if (dflag) {
- X va_start(s);
- X dprintf(dbgout,fmt,s);
- X putc('\n',logfp);
- X va_end(s);
- X }
- X longjmp(systrap,code);
- X}
- X
- X/* visible - turn arbitrary character into something visible */
- X
- Xstatic char *visible(c)
- Xregister int c;
- X{
- X static char buf[5];
- X
- X switch(c&=0377) {
- X default:
- X sprintf(buf,isascii(c) && isprint(c) ? "%c" : "\\%03o",c);
- X return(buf);
- X case ' ':
- X return("\\s");
- X case '\b':
- X return("\\b");
- X case '\t':
- X return("\\t");
- X case '\r':
- X return("\\r");
- X case '\n':
- X return("\\n");
- X case '\f':
- X return("\\f");
- X case '\\':
- X return("\\\\");
- X }
- X}
- X
- X/* dprintf - handle %s, %c, %S and %C format requests */
- X
- Xstatic void dprintf(fp,fmt,s)
- Xregister FILE *fp;
- Xregister char *fmt;
- Xva_list s;
- X{
- X register int c;
- X
- X for (/* void */; c = *fmt; fmt++) {
- X if (c != '%') {
- X putc(c,fp);
- X } else if ((c = *++fmt) == 'S') { /* %S: translated */
- X register char *cp = va_arg(s,char *);
- X while(*cp)
- X fputs(visible(*cp++&0377),fp);
- X } else if (c == 'C') { /* %C: translated */
- X fputs(visible(va_arg(s,int)),fp);
- X } else if (c == 's') { /* %s: string, as is */
- X fputs(va_arg(s,char *),fp);
- X } else if (c == 'c') { /* %c: char, as is */
- X putc(va_arg(s,int),fp);
- X } else if (c == '%') { /* real % character */
- X putc(c,fp);
- X }
- X }
- X}
- END_OF_logs.c
- if test 4714 -ne `wc -c <logs.c`; then
- echo shar: \"logs.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f path.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"path.h\"
- else
- echo shar: Extracting \"path.h\" \(4342 characters\)
- sed "s/^X//" >path.h <<'END_OF_path.h'
- X/*++
- X/* NAME
- X/* path
- X/* SUMMARY
- X/* system-dependent file name definitions
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* general
- X/* SYNOPSIS
- X/* #include "path.h"
- X/* DESCRIPTION
- X/* File-system dependent definitions should be changed here.
- X/* .nf
- X
- X/* /* the minmal number of open files we think we need */
- X
- X#define MINFILES 10
- X
- X/* /* system-dependent defaults */
- X
- X#ifdef unix
- X#define THISDIR "." /* current directory */
- X#define DEFSPOOL "./spool" /* default spool directory */
- X#define DEFEDIT "vi" /* default editor */
- X#ifdef SIII
- X#define DEFPRINT "lp" /* printer spooler */
- X#else
- X#define DEFPRINT "lpr" /* printer spooler */
- X#endif
- X#define MAILFILE "mail.msg" /* temporary message file */
- X#define TMPALIAS "tmp.alias" /* temp alias file */
- X#define NULLDEV "/dev/null" /* bit dump */
- X#endif
- X
- X#ifdef MSDOS
- X#define THISDIR "." /* current directory */
- X#define DEFSPOOL "\\spool" /* spool directory */
- X#define DEFEDIT "edlin" /* default editor */
- X#define DEFPRINT "PRN" /* default printer */
- X#define MAILFILE "mail.msg" /* temp message file */
- X#define TMPALIAS "alias.tmp" /* temp alias file */
- X#define NULLDEV "NUL" /* bit dump */
- X#endif
- X
- X/* /* system-dependent function calls for file & printer access */
- X
- X#ifdef unix
- X#define propen() popen(mailprn,"w") /* open printe stream */
- X#define prclose(p) pclose(p) /* close print stream */
- X#define fspool(file) strcons("%s/%s",maildir,file)
- X#endif
- X
- X#ifdef MSDOS
- X#define propen() fopen(mailprn,"a") /* open print stream */
- X#define prclose(p) (putc('\014',p),fclose(p)) /* close print stream */
- X#define fspool(file) strcons("%s\\%s",maildir,file)
- X#endif
- X
- X/* /* system-independent file names */
- X
- X#define SMAIL "smail" /* queues a mail message */
- X#define CICO "cico" /* file transfer program */
- X#define RMAIL "rmail" /* extract originator address */
- X
- X/* /*
- X* The spool directory is used for storage of all files manipulated
- X* by the mail programs. Message files should always have a meta file
- X* with information about the destination or origin of a message file.
- X*
- X* Message/meta file names are of the form <letter><sequence number>.
- X* Corresponding message/meta files have the same sequene number.
- X* The following definitions are for the <letter> part of spool files.
- X*/
- X
- X#define LOGFILE "LOGFILE" /* transaction logs */
- X
- X#define NEWPFX "n" /* received message */
- X#define HDRPFX "h" /* originator of new mail */
- X#define OLDPFX "o" /* originator of old mail */
- X
- X#define MSGPFX "d" /* message ready to be sent */
- X#define XQTPFX "x" /* its destination */
- X
- X#define EDTPFX "e" /* message being worked on */
- X#define COMPFX "c" /* its description */
- X
- X#define SETPFX "s" /* system parameter file */
- X
- X#define ALIPFX "a" /* alias data base */
- X
- X#define SPLFMT "%s%05d" /* spool-file name format */
- X
- X/* /*
- X* The following macros provide convenient access of spool files, so we
- X* don't have to remember the spool file name format and prefix stuff.
- X*/
- X
- X#define sendmail(file,to) spoolfil(file,to,MSGPFX,XQTPFX)
- X#define workon(fname,meta) spoolfil(fname,meta,EDTPFX,COMPFX)
- X
- X#define parm_file() fspool(strcons(SPLFMT,SETPFX,0))
- X#define aliases() fspool(strcons(SPLFMT,ALIPFX,0))
- X#define logfile() fspool(LOGFILE)
- X
- X#define meta_file(type,id) fspool(strcons(SPLFMT,type,id))
- X#define mesg_file(type,id) fspool(strcons(SPLFMT,type,id))
- X
- X#define work_meta(id) fspool(strcons(SPLFMT,COMPFX,id))
- X#define work_mesg(id) fspool(strcons(SPLFMT,EDTPFX,id))
- X
- X#define in_mesg(id) fspool(strcons(SPLFMT,NEWPFX,id))
- X#define in_meta(id) fspool(strcons(SPLFMT,OLDPFX,id))
- X
- X#define new_mesg(id) fspool(strcons(SPLFMT,NEWPFX,id))
- X#define new_meta(id) fspool(strcons(SPLFMT,HDRPFX,id))
- X
- X#define out_mesg(id) fspool(strcons(SPLFMT,MSGPFX,id))
- X#define out_meta(id) fspool(strcons(SPLFMT,XQTPFX,id))
- X
- X/* /* stuff taken from the environment */
- X
- Xextern char *editor; /* path to editor */
- Xextern char *maildir; /* spool directory */
- Xextern char *mailprn; /* how to print */
- Xextern char *mailcmd; /* do this on exit */
- X
- Xextern int pathinit(); /* get path info from environment */
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Sun Apr 5 13:23:45 GMT+1:00 1987
- X/* LAST MODIFICATION
- X/* Wed Apr 6 00:21:29 MET 1988
- X/* VERSION/RELEASE
- X/* 1.4
- X/*--*/
- END_OF_path.h
- if test 4342 -ne `wc -c <path.h`; then
- echo shar: \"path.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f sendwork.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"sendwork.c\"
- else
- echo shar: Extracting \"sendwork.c\" \(4326 characters\)
- sed "s/^X//" >sendwork.c <<'END_OF_sendwork.c'
- X/*++
- X/* NAME
- X/* sendwork 3
- X/* SUMMARY
- X/* send local work to remote system
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* cico
- X/* SYNOPSIS
- X/* #include "work.h"
- X/*
- X/* void sendwork(wrk)
- X/* work *wrk;
- X/* DESCRIPTION
- X/* sendwork converts names and contents of local work files,
- X/* sends them to the remote system and deletes the files after
- X/* successfull transfer.
- X/*
- X/* In particular, it generates appropriate "From " lines at the
- X/* beginning of an outgoing mail message.
- X/* FUNCTIONS AND MACROS
- X/* rmtname()
- X/* SEE ALSO
- X/* scanwork(3) locates work in the spool directory
- X/* rmtname(3) rules for remote file name construction
- X/* DIAGNOSTICS
- X/* sendwork() returns via longjmp(systrap,errorcode) in case
- X/* of unrecoverable problems.
- X/*
- X/* The error codes are: E_CONFUSED (unexpected work type),
- X/* E_LOST (timed out), E_READERR (file read error).
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Thu Mar 26 11:32:23 GMT+1:00 1987
- X/* LAST MODIFICATION
- X/* Wed Apr 6 00:22:23 MET 1988
- X/* VERSION/RELEASE
- X/* 1.4
- X/*--*/
- X
- X#include <time.h>
- X#include "defs.h"
- X#include "work.h"
- X#include "logs.h"
- X#include "status.h"
- X#include "params.h"
- X#include "comm.h"
- X
- Xextern struct tm *localtime(); /* std C library */
- X
- X/*
- X* A pc-mail system can connect to the UNIX net in at least two modes:
- X*
- X* 1. As a real UUCP node, with it's own node name. This node name will
- X* have to appear in the "From " lines of outgoing mail. A consequence
- X* is that the pc mail node name should be known in mailer routing tables.
- X* Obviously this implies some administrative work when a pc mail node
- X* is added to the net or taken out of operation.
- X*
- X* 2. As an ordinary user. The program lets the UNIX host believe that
- X* mail messages come from an ordinary user. Recipients of mail will
- X* not be able to see that the mail came from the pc. Only the UNIX host
- X* knows it should forward mail for unixhost!xyz to the pc-mail node.
- X* This approach has the advantage that adding/deleting pc-mail nodes
- X* is simpler.
- X*/
- X
- X#ifdef UUCP_NODE /* case 1 */
- X# define U_USER "root" /* use current user's name */
- X# define U_HOST LOGIN_NAME /* use pc host name */
- X#else /* case 2 */
- X# define U_USER LOGIN_NAME /* use remote login name */
- X# define U_HOST rmthost /* use remote host name */
- X#endif
- X
- X/* sendwork - adapt file contents for remote host */
- X
- Xpublic sendwork(wrk)
- Xwork *wrk;
- X{
- X register char *date;
- X long secs;
- X
- X switch (wrk->type) {
- X
- X /*
- X * Local D files contain the mail message, nothing more, nothing less.
- X * We add a "From " line with originator/date/system.
- X * Otherwise, D files can be sent as is.
- X */
- X
- X case 'D':
- X secs = time((long *)0);
- X (date = asctime(localtime(&secs)))[24] = '\0';
- X say(strcons("From %s %s remote from %s\n",U_USER,date,U_HOST));
- X send_file(wrk->fp);
- X break;
- X
- X /*
- X * Local X files contain the destination network address only.
- X * Therefore we must mock up some extra info to make the
- X * remote uuxqt program happy.
- X */
- X
- X case 'X':
- X say(strcons("U %s %s\n",U_USER,U_HOST)); /* U user system */
- X say(strcons("F %s\n",rmtname('D',wrk->tail))); /* F D.rmtsysGnumber */
- X say(strcons("I %s\n",rmtname('D',wrk->tail))); /* I D.rmtsysGnumber */
- X say("C rmail "); /* C rmail */
- X send_file(wrk->fp); /* send destination */
- X break;
- X
- X default:
- X trap(E_CONFUSED,"INTERNAL ERROR (unexpected work type: %c)",wrk->type);
- X }
- X}
- X
- X/* say - write string to host */
- X
- Xhidden say(str)
- Xchar *str;
- X{
- X if (CALL(Write)(ttfd,str,strlen(str)) < 0)
- X trap(E_LOST,"FAILED (link lost)");
- X}
- X
- X/* send_file - do the nitty-gritty of file transfer; traps on all errors */
- X
- Xhidden send_file(fp)
- Xregister FILE *fp;
- X{
- X register int nread,nwrite = 0;
- X char buf[BUFSIZ];
- X register int rerror;
- X
- X while ((nread = fread(buf,sizeof(*buf),sizeof(buf),fp)) > 0 &&
- X (nwrite = CALL(Write)(ttfd,buf,nread)) == nread)
- X /* empty */;
- X rerror = ferror(fp);
- X fclose(fp);
- X
- X if (rerror) {
- X trap(E_READERR,"FILE READ ERROR (%s)",sys_errlist[errno]);
- X /* NOTREACHED */
- X } else if (nwrite < 0 || CALL(Write)(ttfd,buf,0) != 0) {
- X trap(E_LOST,"FAILED (link lost)");
- X /* NOTREACHED */
- X }
- X}
- END_OF_sendwork.c
- if test 4326 -ne `wc -c <sendwork.c`; then
- echo shar: \"sendwork.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f spoolfil.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"spoolfil.c\"
- else
- echo shar: Extracting \"spoolfil.c\" \(4020 characters\)
- sed "s/^X//" >spoolfil.c <<'END_OF_spoolfil.c'
- X/*++
- X/* NAME
- X/* spoolfil,metafile 3
- X/* SUMMARY
- X/* create message file and meta file
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* general utilities
- X/* SYNOPSIS
- X/* int spoolfil(mesg,meta_info,mesg_prefix,meta_prefix)
- X/* char *mesg;
- X/* char *meta_info;
- X/* char *mesg_prefix;
- X/* char *meta_prefix;
- X/*
- X/* int metafile(string,path)
- X/* char *string;
- X/* char *path;
- X/* DESCRIPTION
- X/* spoolfil() creates a message, meta file pair in the spool
- X/* directory.
- X/*
- X/* "mesg" should be null-terminated string with the name of an existing
- X/* file. The contents of that file are filtered to produce a
- X/* clean ASCII file.
- X/*
- X/* "meta-info" is a string with additional information that is
- X/* written to a meta file (usually name of mail recipient, mail
- X/* originator or a comment describing the contents of the message file).
- X/*
- X/* "mesg_prefix," "meta_prefix" are strings that will be used for building
- X/* names for files in the spool directory.
- X/*
- X/* metafile() creates a file, writes a string to it and terminates
- X/* the file with a newline character. This function is typically used
- X/* to create a file with meta information (mail originator, message
- X/* summary etc.).
- X/* FUNCTIONS AND MACROS
- X/* ascopen(), ascget(), ascclose(), newseqno()
- X/* DIAGNOSTICS
- X/* A nonzero return value indicates an error condition (see status.h)
- X/* SEE ALSO
- X/* status(5) return values
- X/* ascf(3) ASCII filter
- X/* BUGS
- X/* Wordprocessor control codes etc will be lost when spoolfil copies
- X/* a file.
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Mon May 18 18:45:10 GMT+1:00 1987
- X/* LAST MODIFICATION
- X/* Mon Apr 4 23:50:14 MET 1988
- X/* VERSION/RELEASE
- X/* 1.3
- X/*--*/
- X
- X#include "defs.h"
- X#include "path.h"
- X#include "ascf.h"
- X#include "status.h"
- X
- X/* metafile - create a one-liner file */
- X
- Xpublic int metafile(string,file)
- Xchar *string;
- Xchar *file;
- X{
- X register FILE *fp;
- X
- X if ((fp = fopen(file,"w")) == 0) {
- X return(E_WRITERR);
- X } else if (fprintf(fp,"%s\n",string),ferror(fp)) {
- X fclose(fp);
- X return(E_WRITERR);
- X } else {
- X fclose(fp);
- X return(0);
- X }
- X}
- X
- X/* spoolfil - make arbitrary spool file */
- X
- Xpublic int spoolfil(fname,meta,msgpfx,auxpfx)
- Xchar *fname;
- Xchar *meta;
- Xchar *msgpfx;
- Xchar *auxpfx;
- X{
- X register int newid = newseqno(); /* new message id */
- X register int stat; /* some status */
- X char *msgpath; /* new message file */
- X char *auxpath; /* new meta file */
- X
- X msgpath = mesg_file(msgpfx,newid); /* message file path */
- X auxpath = meta_file(auxpfx,newid); /* meta file path */
- X
- X /* copy disk file to spool file, check for errors */
- X
- X if (stat = copyfile(fname,msgpath)) { /* read/write error */
- X unlink(msgpath); /* delete msg file */
- X return(stat); /* notify caller */
- X
- X /* create file for meta information, check for errors */
- X
- X } else if (stat = metafile(meta,auxpath)) { /* metafile error */
- X unlink(msgpath); /* delete msg file */
- X unlink(auxpath); /* delete meta file */
- X return(stat); /* notify caller */
- X
- X /* when nothing went wrong */
- X
- X } else {
- X chmod(msgpath,0444); /* message read-only */
- X chmod(auxpath,0444); /* metafile read-only */
- X return(0); /* own error handling */
- X }
- X}
- X
- X/* copyfile - copy a file and filter it */
- X
- Xpublic int copyfile(from,to)
- Xchar *from;
- Xchar *to;
- X{
- X register FILE *in,*out; /* file pointers */
- X int rerr,werr; /* error status */
- X
- X if ((in = ascopen(from,"r")) == 0) { /* cannot read ?? */
- X return(E_READERR);
- X } else if ((out = fopen(to,"w")) == 0) { /* cannot write */
- X ascclose(in);
- X return(E_WRITERR);
- X } else {
- X register int c;
- X while ((c = ascget(in)) != EOF) /* ASCII filter */
- X putc(c,out);
- X rerr = ferror(in); /* check read status */
- X werr = ferror(out); /* check write status */
- X ascclose(in);
- X fclose(out);
- X if (rerr) {
- X return(E_READERR);
- X } else if (werr) {
- X return(E_WRITERR);
- X } else {
- X return(0);
- X }
- X }
- X}
- END_OF_spoolfil.c
- if test 4020 -ne `wc -c <spoolfil.c`; then
- echo shar: \"spoolfil.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f srctoman.sh -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"srctoman.sh\"
- else
- echo shar: Extracting \"srctoman.sh\" \(4444 characters\)
- sed "s/^X//" >srctoman.sh <<'END_OF_srctoman.sh'
- X: srctoman - see comment below
- X
- X: process arguments
- X
- Xwhile :
- Xdo
- X case $1 in
- X [0-9]) SECT=$1;;
- X -) LANG=$1; B='[#:]';;
- X -awk) LANG=$1; B='#';;
- X -c) LANG=$1; B='\/\*';;
- X -f) LANG=$1; B='[Cc]';;
- X -mk) LANG=$1; B='#';;
- X -n|-t) LANG=$1; B='\\"';;
- X -p) LANG=$1; B='{';;
- X -r) LANG=$1; B='#';;
- X -C) LANG=$1; B=$2; shift;;
- X -*) ERROR="unknown option: $1"; break;;
- X "") ERROR="missing file argument"; break;;
- X *) break;;
- X esac
- X shift
- Xdone
- X
- X: check error status
- X
- Xcase $ERROR in
- X"") ;;
- X *) echo "$0: $ERROR" 1>&2
- X echo "usage: $0 [-|-awk|-c|-f|-mk|-n|-p|-t|-r] [section] file(s)" 1>&2; exit 1;;
- Xesac
- X
- X: set up for file suffix processing
- X
- Xcase $LANG in
- X"") sh='[:#]'; r='#'; rh=$r; awk='#'; mk='#';
- X c='\/\*'; h=$c; y=$c; l=$c;
- X f='[Cc]'; fh=$f; p='{'; ph=$p;
- X ms='\\"'; nr=$ms; mn=$ms; man=$ms;
- Xesac
- X
- X: extract comments
- X
- Xfor i in $*
- Xdo
- X case $LANG in
- X "") eval B\="\$`expr $i : '^.*\.\([^.]*\)$'`"
- X test "$B" || { echo "$0: unknown suffix: $i; assuming c" 1>&2; B=$c; }
- X esac
- X sed '
- X /^'"$B"'++/,/^'"$B"'--/!d
- X /^'"$B"'++/d
- X /^'"$B"'--/d
- X s/[ ]*$//
- X /^'"$B"' \([A-Z]\)/{
- X s//\1/
- X /^NAME/{
- X N
- X s/^.*\n'"$B"'[ ]*//
- X h
- X y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
- X s/^.*$/.TH & '"$SECT"'\
- X.ad\
- X.fi\
- X.SH NAME/
- X p
- X g
- X s/ [0-9]$//
- X a\
- X\\-
- X p
- X d
- X }
- X /^SUMMARY/d
- X /^DESCRIPTION/s//.SH &\
- X.ad\
- X.fi/
- X /^BUGS/s//.SH &\
- X.ad\
- X.fi/
- X /^DIAGNOSTICS/s//.SH &\
- X.ad\
- X.fi/
- X /^[A-Z][A-Z][A-Z][^a-z]*$/s//.SH &\
- X.na\
- X.nf/
- X p
- X d
- X }
- X s/^'"$B"'[ ]*//
- X s/^[ ]*$//
- X' $i
- Xdone
- X
- Xexit
- X
- X:++
- X: NAME
- X: srctoman 1
- X: SUMMARY
- X: extract manual page from source file comment
- X: PACKAGE
- X: source file maintentance tools
- X: SYNOPSIS
- X: srctoman [-|-awk|-c|-f|-mk|-m|-n|-p|-t|-r] [section] file(s)
- X: DESCRIPTION
- X: Srctoman converts comments in various programming languages to
- X: UNIX-style manual pages.
- X: The command processes comments in the style of newsource(1);
- X: its standard output is suitable for formatting with nroff(1) or
- X: troff(1) using the "-man" macro package.
- X: Typically, srctoman is integrated with make(1) scripts.
- X:
- X: Source files are processed in the indicated order; if no
- X: files argument the command produces no output.
- X:
- X: The source file language can be specified through a command-line
- X: option, or can be implied by the filename suffix.
- X: The expected start-of-comment symbol is shown in the last column.
- X:
- X: .nf
- X option language comment
- X
- X - shell [:#]
- X -awk awk #
- X -c c /*
- X -f fortran [Cc]
- X -mk make #
- X -n nroff \\"
- X -p pascal {
- X -t troff \\"
- X -r ratfor #
- X -C any language next argument
- X: .fi
- X:
- X: .nf
- X suffix language comment
- X
- X .awk awk #
- X .c c /*
- X .f fortran [Cc]
- X .fh fortran [Cc]
- X .h c /*
- X .l lex /*
- X .man nroff,troff \\"
- X .mk make #
- X .me nroff,troff \\"
- X .ms nroff,troff \\"
- X .nr nroff,troff \\"
- X .p pascal {
- X .ph pascal {
- X .r ratfor #
- X .rh ratfor #
- X .sh shell [:#]
- X .y yacc /*
- X: .fi
- X:
- X: The required format of comments is discussed below, where SOC
- X: stands for the start-of-comment symbol of the language being used.
- X:
- X: 1) Start of manual: SOC, followed by `++'.
- X:
- X: 2) Section heading: SOC, blank, section name in upper case.
- X:
- X: 3) New paragraph: empty line or line with SOC only.
- X:
- X: 4) All other text: SOC and subsequent blanks or tabs are removed.
- X: Lines that do not start with SOC are left unchanged (useful for
- X: inclusion of program text).
- X:
- X: 5) End of manual: SOC, followed by `--'.
- X: An end-of-comment may follow if the source file language requires this.
- X:
- X: The following manual sections receive a special treatment:
- X: NAME and SUMMARY should appear at the beginning and in
- X: this order; DESCRIPTION, DIAGNOSTICS and BUGS will be
- X: right-margin adjusted.
- X: Other sections may be added freely without confusing srctoman.
- X: COMMANDS
- X: sh(1), sed(1), expr(1)
- X: SEE ALSO
- X: newsource(1), modsource(1), xman(1)
- X: The earlier commands new(1), mod(1), mkman(1) and dssman(1)
- X: by Ruud Zwart and Ben Noordzij (Erasmus University, Rotterdam)
- X: DIAGNOSTICS
- X: The program complains if an unknown language is specified
- X: or if the language cannot be deduced from the file suffix.
- X: AUTHOR(S)
- X: W.Z. Venema
- X: Eindhoven University of Technology
- X: Department of Mathematics and Computer Science
- X: Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X: CREATION DATE
- X: Fri Jan 17 22:59:27 MET 1986
- X: LAST MODIFICATION
- X: Thu Mar 10 20:08:15 MET 1988
- X: VERSION/RELEASE
- X: 1.20
- X:--
- X
- X
- END_OF_srctoman.sh
- if test 4444 -ne `wc -c <srctoman.sh`; then
- echo shar: \"srctoman.sh\" unpacked with wrong size!
- fi
- chmod +x srctoman.sh
- # end of overwriting check
- fi
- if test -f switcher.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"switcher.c\"
- else
- echo shar: Extracting \"switcher.c\" \(4041 characters\)
- sed "s/^X//" >switcher.c <<'END_OF_switcher.c'
- X/*++
- X/* NAME
- X/* switcher 3
- X/* SUMMARY
- X/* master/slave protocol control switcher
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* cico
- X/* SYNOPSIS
- X/* int switcher(role)
- X/* int role;
- X/* DESCRIPTION
- X/* switcher() takes care of the high-level protocol on top of
- X/* the packet protocol.
- X/*
- X/* The system is in one of two roles: MASTER or SLAVE. In MASTER
- X/* mode (initial mode of the caller) a system scans its local
- X/* spool directory for work until no more is found, and then
- X/* sends a H (hangup) request. The slave will respond with HY
- X/* if it has no work, otherwise it will respond with HN and
- X/* the two systems switch roles.
- X/*
- X/* Work can be of the form of S (send) requests or R (receive)
- X/* requests. The slave responds with SY (RY) or SN (RN), depending on
- X/* whether it is willing to process the request. The recipient
- X/* of a message sends a CY or CN message, depending on whether
- X/* transmission was successfull.
- X/*
- X/* Only H(angup) and S(end) requests are implemented here. This is
- X/* for security reasons. Thus, the only way to exchange data is
- X/* through electronic mail.
- X/* FUNCTIONS AND MACROS
- X/* isok, talk(), hear(), trap(), scanwork(), sendwork()
- X/* rmtwork(), getwork()
- X/* DIAGNOSTICS
- X/* Various nonzero status codes are returned in case of problems.
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Fri Mar 27 21:49:16 GMT+1:00 1987
- X/* LAST MODIFICATION
- X/* Wed Apr 6 00:23:14 MET 1988
- X/* VERSION/RELEASE
- X/* 1.4
- X/*--*/
- X
- X#include <setjmp.h>
- X#include "defs.h"
- X#include "work.h"
- X#include "params.h"
- X#include "comm.h"
- X#include "logs.h"
- X#include "status.h"
- X
- X/* switcher - handles master/slave role swicthing until all work is done */
- X
- Xpublic switcher(role)
- Xregister int role;
- X{
- X int *savetrap = systrap;
- X jmp_buf mytrap;
- X int status;
- X
- X if (status = setjmp(systrap = mytrap)) {
- X systrap = savetrap; /* get here on fatal errors */
- X return(status);
- X }
- X
- X /* switch roles until both ends out of work */
- X
- X while (role != DONE) {
- X switch (role) {
- X case MASTER:
- X role = master();
- X break;
- X case SLAVE:
- X role = slave();
- X break;
- X default:
- X trap(E_CONFUSED,"INTERNAL ERROR (unexpected role: %d)",role);
- X }
- X }
- X systrap = savetrap; /* get here if no fatal errors */
- X return(0);
- X}
- X
- X/* master - process local work; when done, switch roles or finish */
- X
- Xhidden int master()
- X{
- X register work *wrk;
- X register char *resp;
- X
- X while (wrk = scanwork()) { /* scan for work */
- X log("REQUEST (%s)",wrk->rqst);
- X if (wrk->fp == 0) { /* check file exists */
- X log("CAN'T READ DATA (%s)",sys_errlist[errno]);
- X } else if (isok(wrk->rqst) == NO) { /* check xfer allowed */
- X log("PERMISSION (DENIED)");
- X } else { /* adapt + send data */
- X sendwork(wrk);
- X log("REQUESTED (%s)",resp = hear());
- X if (strcmp(resp,"CY")) /* check sucessfull */
- X trap(E_REJECT,"FAILED"); /* completion */
- X chmod(wrk->path,0666); /* delete workfile */
- X unlink(wrk->path); /* only if all well */
- X }
- X }
- X
- X /* switch roles or finish if slave has no work */
- X
- X return(isok("H") == YES ? (talk("HY"),DONE) : SLAVE);
- X}
- X
- X/* slave - process remote work; accept H and S requests only */
- X
- Xhidden int slave()
- X{
- X register char *cmnd;
- X register work *wrk;
- X
- X for (;;) {
- X switch ((cmnd = hear())[0]) {
- X case 'S': /* master wants to send */
- X log("REQUESTED (%s)",cmnd); /* log the request */
- X wrk = rmtwork(cmnd); /* parse the request */
- X talk("SY"); /* say ok */
- X getwork(wrk); /* receive work */
- X talk("CY"); /* we never copy */
- X log("COPY (SUCCEEDED)");
- X break;
- X case 'H': /* master is out of work */
- X return(scanwork() ? (talk("HN"),MASTER) : (talk("HY"),DONE));
- X default:
- X talk(strcons("%cN",cmnd[0])); /* refuse other type of work */
- X break;
- X }
- X }
- X}
- END_OF_switcher.c
- if test 4041 -ne `wc -c <switcher.c`; then
- echo shar: \"switcher.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f unalias.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"unalias.c\"
- else
- echo shar: Extracting \"unalias.c\" \(4581 characters\)
- sed "s/^X//" >unalias.c <<'END_OF_unalias.c'
- X/*++
- X/* NAME
- X/* unalias 3
- X/* SUMMARY
- X/* alias processing
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* smail
- X/* SYNOPSIS
- X/* char **unalias(namevec)
- X/* char **namevec;
- X/* DESCRIPTION
- X/* unalias() takes an array of string pointers and returns a vector
- X/* with string pointers to their alias expansions. The resulting
- X/* vector is in static memory.
- X/*
- X/* After alias expansion, all addresses are sorted and duplicate
- X/* names are eliminated. The algorithms for alias expansion and
- X/* duplicate elimination are case-insensitive.
- X/*
- X/* unalias() accesses the alias data base through the ascf ASCII
- X/* filter.
- X/* DIAGNOSTICS
- X/* unalias() returns a null pointer in case of memory-allocation problems.
- X/*
- X/* unalias() terminates prematurely when the alias expansion has
- X/* produced BUFSIZ recipients. This provides some defense against
- X/* cycles in the alias data base. It is up to the caller to
- X/* recognize this condition.
- X/* BUGS
- X/* The overflow/cycle detection algorithm is inelegant.
- X/* FILES
- X/* Alias data base in spool directory
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Wed Apr 6 20:21:35 MET 1988
- X/* LAST MODIFICATION
- X/* Wed Apr 6 20:21:35 MET 1988
- X/* VERSION/RELEASE
- X/* 1.0
- X/*--*/
- X
- X#include "defs.h"
- X#include "hsearch.h"
- X#include "path.h"
- X#include "ascf.h"
- X
- X/* forward declarations */
- X
- Xhidden int hash_alias();
- Xhidden void sort_alias();
- Xhidden void uniq_alias();
- Xhidden char **find_alias();
- X
- X/* unalias - replace aliases by their equivalents */
- X
- Xpublic char **unalias(names)
- Xchar **names;
- X{
- X static int dohash = 1; /* hash table not yet made */
- X static char *recp[BUFSIZ+1]; /* the result of alias expansion */
- X char **stop = recp+BUFSIZ; /* overflow limit */
- X
- X if (dohash && (dohash = hash_alias())) /* build the hash table */
- X return(0);
- X if (stop > find_alias(names,recp,stop)) { /* build vector of addresses */
- X sort_alias(recp); /* sort the recp list */
- X uniq_alias(recp); /* squeeze out identical addresses */
- X }
- X return(recp);
- X}
- X
- X/* hash_alias - copy alias data base to hash table */
- X
- Xhidden int hash_alias()
- X{
- X register FILE *fp;
- X char buf[BUFSIZ];
- X
- X /* initialize the hash table */
- X
- X if (hcreate(BUFSIZ) == 0)
- X return(-1);
- X
- X /*
- X * Lines in the alias data base are of the form
- X *
- X * <left-hand part> <right-hand part>
- X *
- X * where the l.h. part is an alias, and the r.h. part one or more
- X * words. Of course, those words can be aliases. The order in which
- X * aliases are defined is not important. The alias data base is used
- X * only after it has been loaded into memory.
- X *
- X * Each l.h. part is used as the key for finding the r.h. part in the
- X * hash table. The r.h. part is stored as a vector of pointers to strings.
- X */
- X
- X if (fp = ascopen(aliases(),"r")) { /* read through ASCII filter */
- X while (fgets(buf,BUFSIZ,fp)) { /* read alias entry */
- X register char **cpp;
- X ENTRY e;
- X if ((cpp = strvec(buf,", \t\r\n")) == 0) /* split alias entry */
- X return(-1);
- X if ((e.key = *cpp) /* left-hand part exists */
- X && (e.data = (char *) (cpp+1)) /* right-hand part exists */
- X && (hsearch(e,ENTER) == 0)) /* enter hash table */
- X return(-1);
- X }
- X ascclose(fp);
- X }
- X return(0);
- X}
- X
- X/* find_alias - recursively expand aliases */
- X
- Xhidden char **find_alias(from,to,stop)
- Xchar **from;
- Xregister char **to;
- Xregister char **stop;
- X{
- X register char **cpp;
- X register ENTRY *sp;
- X
- X /* recursively replace aliases, but don't crash in case of cycles */
- X
- X for (cpp = from; *cpp && (to < stop); cpp++) {
- X ENTRY e;
- X e.key = *cpp;
- X if (sp = hsearch(e,FIND)) {
- X to = find_alias((char **)sp->data,to,stop);
- X } else {
- X *to++ = *cpp;
- X }
- X }
- X *to = 0;
- X return(to);
- X}
- X
- X/* Istrcmp - interface between qsort and istrcmp */
- X
- Xhidden int Istrcmp(p1,p2)
- Xchar **p1,**p2;
- X{
- X return(istrcmp(*p1,*p2));
- X}
- X
- X/* sort_alias - sort the addresses after alias substitutions */
- X
- Xhidden void sort_alias(to)
- Xchar **to;
- X{
- X register char **cpp;
- X int istrcmp();
- X
- X /* find out length of the list */
- X
- X for (cpp = to; *cpp; cpp++)
- X /* void */ ;
- X
- X /* sort the list */
- X
- X qsort((char *)to,cpp-to,sizeof(*to),Istrcmp);
- X}
- X
- X/* uniq_alias - collapse sequences of identical addresses */
- X
- Xhidden void uniq_alias(to)
- Xchar **to;
- X{
- X register char **in = to;
- X register char **out = to;
- X
- X while (*out = *in) {
- X while (*++in && istrcmp(*out,*in) == 0) {
- X /* void */ ;
- X }
- X ++out;
- X }
- X}
- END_OF_unalias.c
- if test 4581 -ne `wc -c <unalias.c`; then
- echo shar: \"unalias.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- echo shar: End of archive 5 \(of 8\).
- cp /dev/null ark5isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 8 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- uucp: mcvax!eutrc3!wswietse | Eindhoven University of Technology
- bitnet: wswietse@heithe5 | Dept. of Mathematics and Computer Science
- surf: tuerc5::wswietse | Eindhoven, The Netherlands.
-